package com.netty.pro.netty.heartbeat;

import io.netty.bootstrap.ServerBootstrap;
import io.netty.channel.ChannelFuture;
import io.netty.channel.ChannelInitializer;
import io.netty.channel.ChannelPipeline;
import io.netty.channel.EventLoopGroup;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.SocketChannel;
import io.netty.channel.socket.nio.NioServerSocketChannel;
import io.netty.handler.logging.LoggingHandler;
import io.netty.handler.timeout.IdleStateHandler;

import java.util.concurrent.TimeUnit;

/**
 * @author xuzn
 * @ClassName: MyServer
 * @ProjectName netty-pro
 * @date 2020/3/16/9:44
 */
public class MyServer {
  public static void main(String[] args) throws Exception {
    EventLoopGroup bossGroup = new NioEventLoopGroup(1);
    EventLoopGroup workerGroup = new NioEventLoopGroup(8);
    try {
      ServerBootstrap bootstrap = new ServerBootstrap();
      bootstrap.group(bossGroup, workerGroup).channel(NioServerSocketChannel.class)
              .handler(new LoggingHandler())
              .childHandler(new ChannelInitializer<SocketChannel>() {
                @Override
                protected void initChannel(SocketChannel ch) throws Exception {
                  ChannelPipeline pipeline = ch.pipeline();
                  /**
                   * IdleStateHandler:netty处理空闲状态的处理器
                   * 参数1:readerIdleTime表示多长时间没有读,就会发送一个心跳检测包
                   * 参数2:writerIdleTime表示多长时间没有写,就会发送一个心跳检测包
                   * 参数3:allIdleTime表示多长时间没有读写,就会发送一个心跳检测包
                   * 当Channel一段时间未执行读取，写入或两者未执行时，触发IdleStateEvent。
                   * Triggers an IdleStateEvent when a  Channel has not performed read,
                   * write, or both operation for a while
                   * 当IdleStateEvent触发后,就会传递给管道的下一个handler去处理,通过调用下一个handler的userEventTriggered
                   */
                  pipeline.addLast(
                          new IdleStateHandler(3, 5, 7, TimeUnit.SECONDS));
                  // 加入一个堆空闲检测进一步处理的handler)
                  pipeline.addLast(new MyServerHandler());
                }
              });
      ChannelFuture channelFuture = bootstrap.bind(7000).sync();
      channelFuture.channel().closeFuture().sync();
    } finally {
      bossGroup.shutdownGracefully();
      workerGroup.shutdownGracefully();
    }
  }
}
